"""
多重继承-A继承B、C、D
-可以避免设计太多层次复杂的继承关系

在 Python 中，当一个类继承自多个父类时，会按照所谓的 **"Method Resolution Order" (MRO)** 来确定方法的调用顺序。MRO 是一种确定多继承类方法解析顺序的算法，其实际顺序由类的继承顺序所决定。

假设类A继承自B、C、D，而这三个父类都有一个名为 `eat()` 的方法。那么当类A的实例对象调用 `eat()` 方法时，解析顺序会遵循以下原则：

1. 首先，会优先搜索类A中是否有 `eat()` 方法，如果有，则直接调用类A的方法。
2. 如果类A中没有 `eat()` 方法，那么按照类A的继承顺序（即继承时的括号中的顺序），依次在父类B、C、D中查找 `eat()` 方法。
3. MRO 算法会优先选择父类B的 `eat()` 方法，然后是C的，最后是D的。这就是遵循C3线性化算法的MRO。

因此，最终调用的是父类B的 `eat()` 方法。这是因为在多继承的情况下，MRO 算法保证了方法的查找顺序是一致的，并且保证了继承链的一致性。

Version: 0.1
Author: yuwl
Date：2024-3-28
"""

class Father(object):

    def __init__(self, name):
        self._name = name

    def gamble(self):
        print('%s正在打麻将。' % self._name)

    def eat(self):
        print('%s在大吃大喝。' % self._name)

    
class Monk(object):

    def __init__(self, name):
        self._name = name

    def eat(self):
        print('%s在吃斋' % self._name)

    def chant(self):
        print('%s在念经' % self._name)


class Musician(object):

    def __init__(self, name):
        self._name = name

    def eat(self):
        print('%s在细嚼慢咽。' % self._name)

    def play_piano(self):
        print('%s在弹钢琴' % self._name)

# 试一试下面代码看看有什么区别    
# class Son(Father, Monk, Musician):
# class Son(Monk, Father, Musician):
class Son(Musician, Monk, Father):

    def __init__(self, name):
        Father.__init__(self, name)
        Monk.__init__(self, name)
        Musician.__init__(self, name)

    
if __name__ == '__main__':
    son = Son('张三')
    son.gamble()
    son.eat()
    son.chant()
    son.play_piano()